package org.biubiu0002.baiblog.core.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.biubiu0002.baiblog.common.constants.CacheConstants;
import org.biubiu0002.baiblog.core.dao.ShareDao;
import org.biubiu0002.baiblog.core.dao.ShareFavorCountDao;
import org.biubiu0002.baiblog.core.model.entity.ShareEntity;
import org.biubiu0002.baiblog.core.model.entity.ShareFavorCountEntity;
import org.biubiu0002.baiblog.core.service.ShareFavorCountService;
import org.biubiu0002.baiblog.core.utils.IdGenerator;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @Author: biubiu0002
 * @Date: 2022-05-15 16:53
 **/
@Service
@Slf4j
public class ShareFavorCountServiceImpl extends ServiceImpl<ShareFavorCountDao, ShareFavorCountEntity> implements ShareFavorCountService {

    @Resource
    private ShareDao shareDao;

    @Resource
    private ShareFavorCountDao shareFavorCountDao;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private RedissonClient redissonClient;


    @Override
    public int getShareFavorCountFromDB(String shareId) {
        ShareFavorCountEntity shareFavorCountEntity = this.getOne(new QueryWrapper<ShareFavorCountEntity>()
                .eq("share_id", shareId)
                .eq("is_deleted",0)
        );
        if(shareFavorCountEntity==null){
            return 0;
        }
        return shareFavorCountEntity.getFavorCount();
    }

    @Override
    public Integer getShareFavorCount(String shareId) {
        String s = redisTemplate.opsForValue().get(CacheConstants.getShareFavorCountKey(shareId));
        int res = 0;
        if (StringUtils.isBlank(s)) {
            //缓存失效 从db中读
            RLock lock = redissonClient.getLock(CacheConstants.getShareFavorCountLock(shareId));
            try {
                lock.lock();
                int shareFavorCountFromDB = this.getShareFavorCountFromDB(shareId);
                redisTemplate.opsForValue().set(CacheConstants.getShareFavorCountKey(shareId), String.valueOf(shareFavorCountFromDB),
                        CacheConstants.getShareFavorCountExpireMinutes(), TimeUnit.MINUTES);
                res = shareFavorCountFromDB;

            } catch (Exception e) {
                log.error("shareFavorCountFromDB:" + shareId + "从数据库设置到缓存失败", e);
            } finally {
                lock.unlock();
            }
        } else {
            //缓存命中
            res = Integer.parseInt(s);
        }
        return res;
    }

    @Override
    public void syncShareFavorCountFromRedis2DB() {
        Set<String> keys = redisTemplate.keys("BAIBLOG:SHARE:FAVORCOUNT:*");
        if (CollectionUtils.isEmpty(keys)) {
            return;
        }
        for (String key : keys) {
            String[] split = key.split(":");
            String shareId = split[split.length - 1];
            String s = redisTemplate.opsForValue().get(key);
            int favorCount = Integer.parseInt(s);
            //分享不存在的情况
            ShareEntity shareEntity = shareDao.selectOne(new QueryWrapper<ShareEntity>().eq("resource_id", shareId));
            if (shareEntity == null) {
                continue;
            }
            ShareFavorCountEntity shareFavorCountEntity = new ShareFavorCountEntity();
            shareFavorCountEntity.setId(IdGenerator.generateId());
            shareFavorCountEntity.setShareId(shareEntity.getResourceId());
            shareFavorCountEntity.setFavorCount(favorCount);
            shareFavorCountDao.saveOrUpdateIncrease(shareFavorCountEntity);

        }
    }

    @Override
    public void incrementFavorCount(String shareId) {

    }

    @Override
    public void decrementFavorCount(String shareId) {

    }
}
